package com.zhuss.order.processor;

import java.util.Date;

import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Component;

import com.zhuss.bean.bo.order.order.CreatePrepayBo;
import com.zhuss.bean.bo.order.order.PayOrderBo;
import com.zhuss.bean.bo.order.order.WxPayBo;
import com.zhuss.bean.vo.order.order.DetailOrderVo;
import com.zhuss.bean.vo.order.order.PayOrderVo;
import com.zhuss.bean.vo.order.order.WxPayVo;
import com.zhuss.common.AbstractProcessor;
import com.zhuss.common.Processor;
import com.zhuss.db.entity.OpLog;
import com.zhuss.enums.LogActionEnum;
import com.zhuss.enums.MoudleEnum;
import com.zhuss.enums.OrderStatus;
import com.zhuss.exception.DzcxException;
import com.zhuss.exception.ExceptionCode;
import com.zhuss.order.db.dao.ext.OrderDao;
import com.zhuss.order.db.dao.ext.OrderItemDao;
import com.zhuss.order.db.dao.ext.PrepayDao;
import com.zhuss.order.db.entity.Order;
import com.zhuss.order.db.entity.Prepay;
import com.zhuss.order.processor.unuse.OrderUnuse;
import com.zhuss.product.db.dao.ext.TrainDao;
import com.zhuss.util.JsonUtil;
import com.zhuss.util.NoUtil;

/**
 * 创建支付单 processor
 * @Author: zhushanshuo
 * @Date: 2019/9/24 19:54
 */
@Component("orderPay")
public class OrderPay extends AbstractProcessor<PayOrderVo, PayOrderBo> implements Processor<PayOrderVo, PayOrderBo> {

    @Autowired
    private TrainDao trainDao;
    
    @Autowired
    private OrderDao orderDao;
    
    @Autowired
    private OrderItemDao orderItemDao;
    
    @Autowired
	@Qualifier("orderRead")
	private OrderRead orderRead;
    
    @Autowired
    @Qualifier("orderCheck")
    private OrderCheck orderCheck;
    
    @Autowired
    @Qualifier("prepayCreate")
    private Processor<Object, CreatePrepayBo> prepayCreate;
    
    @Autowired
    private PrepayDao prepayDao;
    
    @Autowired
    @Qualifier("wxPayProcessor")
    private Processor<WxPayVo, WxPayBo> wxPayProcessor;
    
    /**
     * 校验
     */
    @Override
    public void check(PayOrderBo param) throws DzcxException {
    	Long orderId = param.getOrderId();
    	if (orderId == null || orderId <= 0) {
    		throw new DzcxException(ExceptionCode.订单ID不存在);
    	}
    	
    	DetailOrderVo order = orderRead.detail(orderId);
    	
    	Long price = param.getPrice();
    	Long dbPrice = order.getPrice();
    	if (!dbPrice.equals(price)) {
    		throw new DzcxException(ExceptionCode.订单价格已过期);
    	}
    	
    	if (!orderCheck.checkPay(order)) {
    		throw new DzcxException(ExceptionCode.当前订单不满足提交支付);
    	}
    	
    	param.setOrder(order);
    	
    }
    
    /**
     * 操作方法
     * @throws DzcxException 
     */
    @Override
    public PayOrderVo process(PayOrderBo param) throws DzcxException {
    	Long orderId = param.getOrderId();
    	DetailOrderVo order = param.getOrder();
    	
		OrderUnuse.startUnuseDecrUsed(order, orderCheck, orderDao, orderItemDao, trainDao, param.getConcurrentUserName(), param.getConcurrentUserId(), OrderStatus.已提交支付.key());
    	
    	if (OrderStatus.已提交支付.sameKey(order.getStatus())) {
    		Prepay prepay = prepayDao.getByOrderId(orderId);
    		WxPayVo vo = new WxPayVo();
    		BeanUtils.copyProperties(prepay, vo);
    		vo.setOrderNo(order.getOrderNo());
    		vo.setPrepayId(prepay.getWxPrepayId());
    		return new PayOrderVo(orderId, vo);
    	}
    	
    	Order record = new Order();
		record.setOrderId(orderId);
		order.setModifierId(param.getConcurrentUserId());
		order.setModifier(param.getConcurrentUserName());
		order.setModifyTime(new Date());
		record.setStatus(OrderStatus.已提交支付.key());
		orderDao.updateByPrimaryKeySelective(record);
		
		orderItemDao.refreshStatus(orderId, OrderStatus.已提交支付.key(), order.getModifier(), order.getModifierId(), order.getModifyTime());
		
		CreatePrepayBo prepayParam = new CreatePrepayBo();
    	BeanUtils.copyProperties(param, prepayParam);
    	BeanUtils.copyProperties(order, prepayParam);
    	prepayParam.setOrderId(order.getOrderId());
    	prepayParam.setTotalPrice(order.getTotalPrice());
    	prepayCreate.process(prepayParam);
    	
    	WxPayBo wxPayParam = new WxPayBo();
    	BeanUtils.copyProperties(param, wxPayParam);
    	wxPayParam.setBody(order.getOnSiteName() + "-" + order.getOffSiteName() + "-" + orderId + "-");
    	wxPayParam.setNonceStr(NoUtil.NONCE + NoUtil.genNonceStr());
    	wxPayParam.setOrderNo(order.getOrderNo());
    	wxPayParam.setTotalPrice(order.getTotalPrice());
    	WxPayVo vo = wxPayProcessor.process(wxPayParam);
    	String wxPrepayId = vo.getPrepayId();
    	
    	Prepay prepay = new Prepay();
    	BeanUtils.copyProperties(vo, prepay);
    	prepay.setPrepayId(prepayParam.getTargetId());
    	prepay.setTime(new Date(vo.getTime() * 1000));
    	prepayDao.updateByPrimaryKeySelective(prepay);
    	
    	prepayDao.refresh(order.getOrderId(), wxPrepayId);
        return new PayOrderVo(order.getOrderId(), vo);
    	
    }
    
    /**
     * 操作日志
     */
	@Override
	public PayOrderVo log(PayOrderBo param) throws DzcxException {
		OpLog record = new OpLog();
    	record.setMoudle(MoudleEnum.订单.key());
    	record.setAction(LogActionEnum.支付单.key());
    	record.setTargetId(param.getOrderId());
    	record.setTargetName(param.getOrderId() + "");
    	record.setContent("参数: " + JsonUtil.toJson(param));
    	record.setReason(param.getExceptionReason());
    	
    	record.setCreatorId(param.getConcurrentUserId());
    	record.setCreator(param.getConcurrentUserName());
    	record.setCreateTime(new Date());
    	log(record);
    	return null;
	}
}
